#include <QFile>
#include <QtXml>

#include <iostream>
#include <fstream>
#include <string.h>
#include <vector>
#include <set>

#include "Omega.hpp"
#include "Variable.hpp"
#include "Outcome.hpp"
#include "Preference.hpp"
#include "PreferenceSet.hpp"
#include "Constraint.hpp"
#include "functions.hpp"

using namespace std;

// Déclaration des fonctions -----------------------
void createResponse(Omega o, vector< vector<int> > res, int sizeE1);
vector<Variable> createVariable(QFile *xmlDoc);
PreferenceSet createPreferenceSet(QFile *xmlDoc);
// Fin --------------------------------------------

int main()
{

    vector<Variable> variables;
    QFile* xmlVar = new QFile("variables.xml");
    variables = createVariable(xmlVar);

    Omega o1(variables);

    QFile* xmlDoc = new QFile("response_form.xml");
    PreferenceSet ps = createPreferenceSet(xmlDoc);
    ps.show();

     vector< vector<int> > res = scpo(ps,o1);
    // Affichage du resultat du calcul de preferences
     for(int i = 0;i<(int)res.size();i++)
     {
         cout<<"E["<<i+1<<"] = {"<<endl;

         for(int j=0;j<(int)res[i].size();j++)
         {
             o1.generateOutcome(res[i][j]).show();
         }
         cout<<"}"<<endl;
     }

     // Récupération de la taille de E1 (soit celle des meilleurs solutions)
     int sizeE1 = res[0].size();

     // Création du fichier XML contenant les réponses
     createResponse(o1, res, sizeE1);


    return 0;
}



// Défintion des fonctions --------------------------------------
void createResponse(Omega o, vector< vector<int> > res, int sizeE1)
{
    // Ouverture/Ecriture du fichier XML
    ofstream flux("solution.xml");
    if(flux)
    {
        flux << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl ;

        int nbValues = o.getNumberOfVariables() ;

        flux << "<allSolutions nbValues=\"" << nbValues << "\">" << endl ;

        for(int i=0 ; i<sizeE1 ; i++)
        {
            // Génération de l'Outcome
            Outcome outcome;
            outcome = o.generateOutcome(res[0][i]);

            flux << "\t<solution " ;

            vector<string> recup = outcome.getValues();
            for(int i = 0 ; i<recup.size() ; i++)
            {
                if(i==0)
                {
                    flux << "background" ;
                }
                else if(i==1)
                {
                    flux << "fontFamily" ;
                }
                else if(i==2)
                {
                    flux << "fontSize" ;
                }
                else
                {
                    flux << "textSpacing" ;
                }
                flux  << "=\"" << recup[i] << "\" " ;
            }

            flux << " />" << endl ;
        }

        flux << "</allSolutions>" ;
    }
    else
    {
        cout << "Erreur d'ouverture du fichier XML" << endl ;
        EXIT_FAILURE;
    }
}

vector<Variable> createVariable(QFile* xmlDoc)
{
    /* Mise en place du fichier XML */
    QDomDocument *dom = new QDomDocument("fileXML");

    if(!xmlDoc->open(QIODevice::ReadOnly))
    {
        cout << "Erreur ouverture du fichier !" << endl ;
        EXIT_FAILURE ;
    }

    if(!dom->setContent(xmlDoc))
    {
        xmlDoc->close();
        cout << "impossible d'attribuer le fichier XML à l'objet QDomDocument" << endl ;
        EXIT_FAILURE ;
    }

    xmlDoc->close();


    /* Lecture du fichier XML ET création du jeu de préférence */
    QDomElement domElt = dom->documentElement();
    QDomNode node = domElt.firstChild();

    vector<Variable> result;
    int nbAttr ;
    while(!node.isNull())
    {
        QDomElement element = node.toElement();
        QString nb = element.attribute("nbAttr");
        nbAttr = nb.toInt();

        QString name = element.attribute("name");
        Variable v(name.toStdString());

        for(int i=1 ; i<=nbAttr ; i++)
        {
            QString value = "value"+QString::number(i);

            /* Récupération des attributs et création de VARIABLE */
            QString valueAttr = element.attribute(value);
            v.addValue(valueAttr.toStdString());
        }
        node = node.nextSibling();

        v.show();
        result.push_back(v);
    }
    return result;
}

PreferenceSet createPreferenceSet(QFile* xmlDoc)
{
    /* Mise en place du fichier XML */
    QDomDocument *dom = new QDomDocument("fileXML");

    if(!xmlDoc->open(QIODevice::ReadOnly))
    {
        cout << "Erreur ouverture du fichier !" << endl ;
        EXIT_FAILURE ;
    }

    if(!dom->setContent(xmlDoc))
    {
        xmlDoc->close();
        cout << "impossible d'attribuer le fichier XML à l'objet QDomDocument" << endl ;
        EXIT_FAILURE ;
    }

    xmlDoc->close();


    /* Lecture du fichier XML ET création du jeu de préférence */
    QDomElement domElt = dom->documentElement();
    QDomNode node = domElt.firstChild();

    PreferenceSet ps;

    while(!node.isNull())
    {
        QDomElement element = node.toElement();
        if(!element.isNull())
        {
            /* Récupération des attributs de chaque balise PREFERENCE */
            QString mostPreferred = element.attribute("mostPreferred");
            QString lessPreferred = element.attribute("lessPreferred");
            QString condition = element.attribute("condition");
            QString semantic = element.attribute("semantic");

            /* Construction de la préférence associée */
            Preference p(mostPreferred.toStdString(), lessPreferred.toStdString(), condition.toStdString());
            p.setSemantic(semantic.toStdString());

            ps.addPreference(p);
        }
        node = node.nextSibling();
    }
    return ps ;
}
